/*
单链表
单链表反转：编写函数，就地反转给定的单链表，改变链表的指针方向使顺序颠倒。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define DATA_TYPE int

typedef struct linklist
{
    DATA_TYPE data;
    struct linklist* next;

}linklist,*p_linklist;

//初始化
p_linklist init_linklist();

//尾插
int list_tail_insert(p_linklist H, DATA_TYPE value);

//反转函数
int reversal_linklist(p_linklist H );

//打印
int print_linklist(p_linklist H);

int main(int argc, char const *argv[])
{
    p_linklist head = init_linklist();
    list_tail_insert(head , 1);
    list_tail_insert(head , 2);
    list_tail_insert(head , 3);
    list_tail_insert(head , 4);
    

    print_linklist(head);
    
    reversal_linklist(head);
    print_linklist(head);

    return 0;
}

//初始化
p_linklist init_linklist()
{
    p_linklist head = (p_linklist)malloc(sizeof(linklist));
    if(head == NULL)
    {
        printf("malloc failed\n");
        return NULL;
    }
    head->data = 0;
    head->next = NULL;
    
    return head;
}

//尾插
int list_tail_insert(p_linklist H, DATA_TYPE value)
{
    //链表是否存在
    if(H==NULL)
    {
        printf("list is error\n");//链表不存在
        return -1;
    }
    //创建一个新的结点
    p_linklist newnode =(p_linklist)malloc(sizeof(linklist)) ; 
    if(newnode==NULL)
    {
        printf("newnode malloc faild\n");
        return -1;
    }
    //将新数据给新结点
    newnode->data=value;
    newnode->next=NULL;//指针域为空
    //找到尾  遍历
    p_linklist p_head=H;//从头结点开始遍历
    while(p_head->next!=NULL)
    {
        p_head=p_head->next;
    }
    //当前phead指向的是尾节点
    p_head->next=newnode;//建议连接

    return 0;
}

//反转函数
int reversal_linklist(p_linklist H )
{
    if(H==NULL)
    {
        printf("list is error\n");//链表不存在
        return -1;
    }
    
    p_linklist Ptail = H;

    while (Ptail->next != NULL)
    {
        Ptail = Ptail->next;
    }

    while (H->next != Ptail)
    {
        p_linklist qhead = H->next;
        H->next =H->next->next;
        qhead->next = Ptail->next;
        Ptail->next = qhead;
    }
    
    return 0;
}

//打印
int print_linklist(p_linklist H)
{
    //判空 判断链表是否存在
    if(H==NULL)
    {
        printf("list is error\n");
        return -1;
        
    }
    //因为是带头结点的单链表
    if(H->next==NULL)
    {
        printf("list is empty\n");
        return -1;
    }
    printf("遍历: ");
    //遍历
    p_linklist phead=H->next;//可以从下一个结点开始遍历
    while(phead)
    {
        printf("%d ",phead->data);
        phead=phead->next;
    }
    printf("\n");
    return 0;
}
